package com.ken.apollo.controller;

import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.ken.apollo.commons.result.R;
import com.ken.apollo.domain.bo.AdminLoginBo;
import com.ken.apollo.domain.bo.ChangePasswordBo;
import com.ken.apollo.domain.vo.AdminUserVo;
import com.ken.apollo.service.AdminUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import jakarta.validation.Valid;

/**
 * 管理员登录控制器
 *
 * @author Ken
 * @since 2025-08-25
 */
@Slf4j
@Controller
public class AdminLoginController {
    
    @Autowired
    private AdminUserService adminUserService;
    
    /**
     * 登录页面
     */
    @GetMapping("/admin/login")
    public String loginPage() {
        return "backs/login";
    }
    
    /**
     * 管理员登录
     */
    @PostMapping("/api/admin/login")
    @ResponseBody
    public R<AdminUserVo> login(@Valid @RequestBody AdminLoginBo loginBo, 
                               HttpServletRequest request,
                               HttpSession session) {
        try {
            String clientIp = getClientIpAddress(request);
            AdminUserVo userVo = adminUserService.login(loginBo, clientIp);
            
            // 将用户信息存入Session
            session.setAttribute("admin_user", userVo);
            session.setMaxInactiveInterval(30 * 60); // 30分钟超时
            
            return R.success(userVo);
        } catch (Exception e) {
            log.error("管理员登录失败：{}", e.getMessage());
            return R.fail(e.getMessage());
        }
    }
    
    /**
     * 管理员注销
     */
    @PostMapping("/api/admin/logout")
    @ResponseBody
    public R<String> logout(HttpSession session) {
        AdminUserVo user = (AdminUserVo) session.getAttribute("admin_user");
        if (user != null) {
            log.info("管理员注销：{}", user.getUsername());
        }
        session.invalidate();
        return R.success("注销成功");
    }
    
    /**
     * 获取当前登录用户信息
     */
    @GetMapping("/api/admin/current")
    @ResponseBody
    public R<AdminUserVo> getCurrentUser(HttpSession session) {
        AdminUserVo user = (AdminUserVo) session.getAttribute("admin_user");
        if (user == null) {
            return R.fail("未登录");
        }
        return R.success(user);
    }
    
    /**
     * 修改密码
     */
    @PostMapping("/api/admin/changePassword")
    @ResponseBody
    public R<String> changePassword(@Valid @RequestBody ChangePasswordBo changePasswordBo,
                                   HttpSession session) {
        try {
            AdminUserVo user = (AdminUserVo) session.getAttribute("admin_user");
            if (user == null) {
                return R.fail("未登录");
            }
            
            boolean result = adminUserService.changePassword(user.getId(), changePasswordBo);
            if (result) {
                return R.success("密码修改成功");
            } else {
                return R.fail("密码修改失败");
            }
        } catch (Exception e) {
            log.error("修改密码失败：{}", e.getMessage());
            return R.fail(e.getMessage());
        }
    }
    
    /**
     * 获取客户端IP地址
     */
    private String getClientIpAddress(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (StrUtil.isNotBlank(xForwardedFor)) {
            return xForwardedFor.split(",")[0].trim();
        }
        
        String xRealIp = request.getHeader("X-Real-IP");
        if (StrUtil.isNotBlank(xRealIp)) {
            return xRealIp;
        }
        
        return request.getRemoteAddr();
    }
    
    /**
     * 测试密码生成（临时接口，用于调试）
     */
    @GetMapping("/api/admin/test-password")
    @ResponseBody
    public R<String> testPassword() {
        String password = "123456";
        
        // 生成新的hash
        String newHash = BCrypt.hashpw(password, BCrypt.gensalt());
        
        // 验证新生成的hash
        boolean newValid = BCrypt.checkpw(password, newHash);
        
        // 测试数据库中的hash
        String dbHash = "$2a$10$K2P2UJh6vZKlcSe1.2Qa5e.YmWZqY1.lIyLHKWTJF0./KyK.z1v.W";
        boolean dbValid = BCrypt.checkpw(password, dbHash);
        
        StringBuilder result = new StringBuilder();
        result.append("原始密码: ").append(password).append("\n");
        result.append("新生成hash: ").append(newHash).append("\n");
        result.append("新hash验证: ").append(newValid).append("\n");
        result.append("数据库hash: ").append(dbHash).append("\n");
        result.append("数据库hash验证: ").append(dbValid).append("\n");
        
        if (!dbValid) {
            result.append("\n推荐使用的正确hash: ").append(newHash);
        }
        
        return R.success(result.toString());
    }
    
    /**
     * 初始化管理员账号（一次性接口，用于修复密码问题）
     */
    @PostMapping("/api/admin/init-admin")
    @ResponseBody
    public R<String> initAdmin() {
        try {
            // 检查是否已经存在admin用户
            com.ken.apollo.domain.entity.AdminUser existingUser = adminUserService.getByUsername("admin");
            
            String password = "123456";
            String hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt());
            
            if (existingUser != null) {
                // 更新密码
                existingUser.setPassword(hashedPassword);
                adminUserService.updateById(existingUser);
                return R.success("管理员密码已重置为123456");
            } else {
                // 创建新管理员
                com.ken.apollo.domain.entity.AdminUser newUser = new com.ken.apollo.domain.entity.AdminUser();
                newUser.setUsername("admin");
                newUser.setPassword(hashedPassword);
                newUser.setRealName("系统管理员");
                newUser.setEmail("admin@apollo.com");
                newUser.setStatus(true);
                adminUserService.save(newUser);
                return R.success("管理员账号创建成功，密码为123456");
            }
        } catch (Exception e) {
            log.error("初始化管理员账号失败", e);
            return R.fail("初始化失败: " + e.getMessage());
        }
    }
}